package com.whately.core.base.fileupload.util;

import com.whately.core.base.exception.ServiceException;
import com.whately.core.base.fileupload.constant.FileModeEnum;
import com.whately.core.base.fileupload.constant.FileStoreTypeEnum;
import com.whately.core.base.fileupload.vo.PathAndNameBo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
public class FileUploadPathCreatorUtil {

    private final static String DATE_PATH_FORMAT="/yyyy/MM/dd/HH/";

    public static PathAndNameBo generateFilePathFromExist(String bucket, FileModeEnum fileModeEnum, String existPath, String originalFileName, String profiles, FileStoreTypeEnum fileStoreTypeEnum){
        PathAndNameBo bo;
        try{
            //格式：  userHeader/local/s2/2019/12/12/17/01e02fe124f0f18221185fba1d3e7a0f3b.jpg?version=1576141483747

            if(StringUtils.countMatches(existPath, ".")<1||existPath.endsWith(".")){
                throw new ServiceException(400,"文件后缀名不符合规范");
            }

            //去掉路径后面的？
            int indexImageViewOrVersion = existPath.indexOf("?");
            if(indexImageViewOrVersion>0){
                existPath = existPath.substring(0,indexImageViewOrVersion);
            }

            //检查是否以bucket开头
            if(existPath.indexOf(bucket)!=0){
                throw new ServiceException(400,"not started with bucket");
            }

            //去掉bucket : /local/s2/2019/12/12/17/01e02fe124f0f18221185fba1d3e7a0f3b.jpg
            existPath = existPath.substring(bucket.length());

            if(existPath.indexOf("/")!=0){
                throw new ServiceException(400,"not started with / profile");
            }
            existPath = existPath.substring(1);//去掉/


            //获取profile
            String profileString = existPath.substring(0,existPath.indexOf("/"));
            if(StringUtils.isBlank(profileString)){
                throw new ServiceException(400,"profileString is blank");
            }

            //路径去掉profile  /s2/2019/12/12/17/01e02fe124f0f18221185fba1d3e7a0f3b.jpg
            existPath = existPath.substring(profileString.length());

            if(existPath.indexOf("/")!=0){
                throw new ServiceException(400,"not started with / qiniu code");
            }
            existPath = existPath.substring(1);//去掉/ ,s2/2019/12/12/17/01e02fe124f0f18221185fba1d3e7a0f3b.jpg

            //获取存储方式code
            String storedTypeCode = existPath.substring(0,existPath.indexOf("/"));
            if(StringUtils.isBlank(storedTypeCode)){
                throw new ServiceException(400,"storedTypeCode is blank");
            }

            //路径去掉七牛store code ： /2019/12/12/17/01e02fe124f0f18221185fba1d3e7a0f3b.jpg
            existPath = existPath.substring(storedTypeCode.length());
            if(existPath.indexOf("/")!=0){
                throw new ServiceException(400,"not started with / yyyy code");
            }

            //检查是否是/yyyy/MM/dd/HH


            int lastIndexOfDot= existPath.lastIndexOf(".");

            String datePathFileNameWithOutSuffix = existPath.substring(0,lastIndexOfDot)  ;
            String dotAndSuffix = existPath.substring(lastIndexOfDot) ;

            //path:   /2019/12/12/17/01e02fe124f0f18221185fba1d3e7a0f3b
            if(datePathFileNameWithOutSuffix.length()<DATE_PATH_FORMAT.length()||dotAndSuffix.length()<=1){
                throw new ServiceException(400,"not correct path or name ");
            }


            if(!checkFileModelInFilePath(datePathFileNameWithOutSuffix)){
                log.error("checkFileModelInFilePath not pass, datePathFileNameWithOutSuffix {}",datePathFileNameWithOutSuffix);
                throw new ServiceException(400,"not correct file mode ");
            }

            bo = new PathAndNameBo();
            bo.setPrefixBeforeDateYYYY(getPrefixForPath(profileString,storedTypeCode));
            bo.setPathAndFileNameWithOutSuffix(datePathFileNameWithOutSuffix);
            bo.setDotAndSuffix(dotAndSuffix);

            String originalPath = bo.getPathAndFileNameWithOutSuffix()+"-original"+dotAndSuffix;
            bo.setOriginalPath(originalPath);

        }catch (Exception e){
            log.error("PathAndNameBo change exist path error , existPath {} ,e {}",existPath,e);
            bo = generateFilePathAndName(bucket,fileModeEnum,originalFileName, profiles, fileStoreTypeEnum);
        }
        return bo;
    }


    //生成文件的路径和名字
    public static PathAndNameBo generateFilePathAndName(String  bucket,FileModeEnum fileModeEnum, String fileOriginalFileName, String profiles, FileStoreTypeEnum fileStoreTypeEnum){
        String prefix =getPrefixForPath ( profiles ,fileStoreTypeEnum);
        String datePath ;
        String fileNameWithOutSuffix;
        String dotAndSuffix ;

        String fileMode= fileModeEnum.getMode();

        if(StringUtils.countMatches(fileOriginalFileName, ".")<1||fileOriginalFileName.endsWith(".")){
            log.error("generateFilePathAndName error,fileOriginalFileName {}", fileOriginalFileName);
            throw new ServiceException(400,"上传的文件后缀名不符合规范");
        }
        int lastIndexOfDot= fileOriginalFileName.lastIndexOf(".");
        dotAndSuffix = fileOriginalFileName.substring(lastIndexOfDot) ;


        log.info("upload image bucket is {}, fileMode is {}", bucket,fileMode);


        datePath = new SimpleDateFormat(DATE_PATH_FORMAT).format(new Date());
        fileNameWithOutSuffix = fileMode
                + DigestUtils.md5Hex( System.currentTimeMillis()+ fileOriginalFileName);

        PathAndNameBo bo = new PathAndNameBo();
        bo.setPrefixBeforeDateYYYY(prefix);
        bo.setPathAndFileNameWithOutSuffix(datePath+fileNameWithOutSuffix);
        bo.setDotAndSuffix(dotAndSuffix);

        String originalPath = bo.getPathAndFileNameWithOutSuffix()+"-original"+dotAndSuffix;
        bo.setOriginalPath(originalPath);
        return bo;
    }


    /**
     * userHeader/local/s2/2019/12/12/17/01e02fe124f0f18221185fba1d3e7a0f3b.jpg?version=1576141483747
     * /2019/12/12/17/01e02fe124f0f18221185fba1d3e7a0f3b
     */
    private static boolean checkFileModelInFilePath(String filePath){
        try{
            String substr = filePath.substring(filePath.lastIndexOf("/")+1);

            FileModeEnum fileMode = FileModeEnum.getByValue(substr.substring(0,2));
            return fileMode==null?false:true;
        }catch (Exception e){
            log.error("checkExistQiNiuBucketInFilePath filePath {} error {}",filePath,e);
            return false;
        }

    }

    /**
     */
    private static String  getPrefixForPath(String profile,FileStoreTypeEnum fileStoreTypeEnum){
        String storedTypeCode="s"+fileStoreTypeEnum.getCode();
        return getPrefixForPath(profile,storedTypeCode);
    }

    private static String  getPrefixForPath(String profile,String storedTypeCode){
        return "/"+ profile +"/"+ storedTypeCode;
    }


}
